// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../../../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("../../utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

// ✅ 是否使用窗口
const useWindow = true;
// ✅ 窗口大小
const windowSize = 5;

// ✅ 存储预测结果
const predictResults = [];
let correct = 0;
let maxWrongStreak = 0;
let currentWrongStreak = 0;

/**
 * ✨ 模运算策略（按“最长遗漏期”排序）
 * - 在 temp 区间内找出每个号码最近出现的位置
 * - 没出现则视为最大遗漏
 * - 选出遗漏最大的 32 个号码
 */
function select32ByLongestOmission(temp) {
  const omissionMap = {}; // 每个号码上次出现的“相对位置”

  // 初始化：默认每个号码都没有出现过
  allNumbers.forEach((num) => {
    omissionMap[num] = temp.length; // 最大值：窗口期数
  });

  // 从窗口尾部往回看，最近出现的越早，值越小
  for (let i = temp.length - 1; i >= 0; i--) {
    const num = temp[i].number;
    if (omissionMap[num] === temp.length) {
      omissionMap[num] = temp.length - 1 - i;
    }
  }

  const sorted = Object.entries(omissionMap)
    .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
    .slice(0, 32)
    .map(([num]) => num);

  if (sorted.length !== 32) {
    throw new Error(`❗ 无法生成 32 个号码，当前仅有 ${sorted.length} 个`);
  }

  return sorted;
}

// ✅ 主循环
allValues.forEach((item, index) => {
  const temp = useWindow
    ? allValues.slice(Math.max(0, index - windowSize), index)
    : allValues.slice(0, index);

  if (temp.length === 0) return;

  const selectedNumbers = select32ByLongestOmission(temp);

  if (selectedNumbers.length !== 32) {
    throw new Error("选出的32个号码数量不正确");
  }

  try {
    const isHit = checkAccuracy(selectedNumbers, item.number);
    if (isHit) {
      correct++;
      currentWrongStreak = 0;
    } else {
      currentWrongStreak++;
      maxWrongStreak = Math.max(maxWrongStreak, currentWrongStreak);
    }

    predictResults.push(selectedNumbers);
  } catch (err) {
    console.error(`❌ checkAccuracy error at index ${index}: ${err.message}`);
  }
});

// ✅ 输出统计结果
const total = predictResults.length;
const accuracy = total > 0 ? ((correct / total) * 100).toFixed(2) : 0;

console.log(`预测总数: ${total}`);
console.log(`命中次数: ${correct}`);
console.log(`准确率: ${accuracy}%`);
console.log(`最大连续错误次数: ${maxWrongStreak}`);
